<html>
<head>
    <meta charset="utf-8">
    <title>中国空气质量地图</title>
</head>

<body>
<link href="https://cdn.bootcss.com/bootstrap/4.0.0-beta.3/css/bootstrap.css" rel="stylesheet">
<link rel="stylesheet" href="css/main.css"/>
<script src="https://d3js.org/d3.v3.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
<script>
    var width = 1000;
    var height = 700;
    var backgroundColor = "#565656";
    var fontColor="#007bff";
    var graphSize = 75;
    var radius = (graphSize / 2) - 10;
    var colorList = [d3.rgb("#D62F27"), d3.rgb('#E04D36'), d3.rgb('#F59D6E'),
        d3.rgb('#FFE5A8'), d3.rgb('#D9E0BF'), d3.rgb("#8DA5BA"), d3.rgb("#507CB5")];
    var rangeList = {
        'AQI': [500, 1],
        'PM25': [200, 1],
        'PM10': [300, 1],
        'CO': [100, 0],
        'O3': [500, 1],
        'SO2': [100, 1],
        'NO2': [100, 1]
    };

    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height)
        .classed("center", true)
        .append("g")
        .attr("transform", "translate(0,0)");
    var globalLayer = svg.append('g')
        .attr('id', 'global_g');
    var baseLayer = globalLayer.append('g')
        .attr('id', 'base_g');
    var graphLayer = globalLayer.append('g')
        .attr('id', 'graph_g');
    var legendLayer = svg.append('g')
        .attr('id', 'legend_g');

    var zoom = d3.behavior.zoom()
        .scaleExtent([0.4, 10])
        .on("zoom", function () {
            globalLayer.attr("transform",
                "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        });

    var cityCoordList = {
        'beijing': [116.24, 39.55],
        'hefei': [117.17, 31.52],
//        'chongqing': [106.54, 29.59],
        'fuzhou': [118.18, 25.05],
        'lanzhou': [104.51, 35.04],
        'guangzhou': [113.14, 23.08],
        'nanning': [108.59, 23.04],
        'guiyang': [106.42, 26.35],
        'haikou': [110.2, 19.02],
//        'shijiazhuang': [114.3, 38.02],
        'zhengzhou': [114.4, 34.46],
        'harbing': [128.36, 46.44],
        'wuhan': [112.17, 31.35],
        'changsha': [111.59, 27.12],
        'changchun': [125.19, 44.54],
        'nanchang': [115.89, 28.18],
//        'nanjing': [118.55, 28.4],
        'shengyang': [123.25, 41.48],
        'hohhot': [111.41, 42.48],
        'yinchuan': [106.16, 38.27],
        'xining': [95.48, 36.38],
        'jinan': [118.5, 36.4],
        'taiyuan': [112.33, 37.54],
        'xian': [108.57, 34.17],
        'shanghai': [121.79, 31, 14],
        'chengdu': [104.04, 30.4],
//        'tianjing': [117.12, 39.02],
        'lhasa': [91.08, 31.02],
        'urumqi': [87.36, 43.35],
        'kunming': [102.1, 25.04],
//        'hangzhou': [120.1, 30.16]
    }

    var projection = d3.geo.mercator()
        .center([107, 34])
        .scale(800)
        .translate([0.5 * width, 0.6 * height]);

    var path = d3.geo.path()
        .projection(projection);

    d3.json("china.geojson", function (error, root) {

        if (error)
            return console.error(error);

        baseLayer.selectAll("path")
            .data(root.features)
            .enter()
            .append("path")
            .attr("id", function (d, i) {
                return d.properties.id ? "g_" + d.properties.id : "";
            })
            .attr("stroke", "#ffffff")
            .attr("stroke-width", 1)
            .attr("fill", function (d, i) {
                return backgroundColor;
            })
            .call(zoom)
            .attr("d", path);
        baseLayer.selectAll("text")
            .data(root.features)
            .enter()
            .append("svg:text")
            .text(function (d) {
                return d.properties.name;
            })
            .attr("x", function (d) {
                return path.centroid(d)[0];
            })
            .attr("y", function (d) {
                return path.centroid(d)[1];
            })
            .attr("text-anchor", "middle")
            .attr("font-size", "6pt")
            .attr("fill", "white");
    });

    var formatNumber = d3.format(".2f");

    var x = d3.scale.linear()
        .range([0, 2 * Math.PI]);

    var y = d3.scale.sqrt()
        .range([0, radius]);

    var partition = d3.layout.partition()
        .sort(null)
        .value(function (d) {
            return 1;
        });

    var arc = d3.svg.arc()
        .startAngle(function (d) {
            return Math.max(0, Math.min(2 * Math.PI, x(d.x)));
        })
        .endAngle(function (d) {
            return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
        })
        .innerRadius(function (d) {
            return Math.max(0, y(d.y));
        })
        .outerRadius(function (d) {
            return Math.max(0, y(d.y + d.dy));
        });

    function insertSunBurstGraph(name, airType, quarter, month) {
        var color = d3.scale.quantize().domain(rangeList[airType])
            .range(colorList);
        var translateCoord = projection(cityCoordList[name]);
        var svgSunBurst = graphLayer
            .append('g')
            .attr('id', 'g_' + name)
            .attr('transform', 'translate(' + translateCoord[0] + ',' + translateCoord[1] + ')');
        d3.json('/airpollutionvis/data/json/' + name + ".json", function (error, root) {
            if (error) throw error;
            if (!(quarter === undefined || quarter === -1))
                root = root.children[quarter];
            if (!(month === undefined || month === -1))
                root = root.children[month];
            svgSunBurst.selectAll("path")
                .data(partition.nodes(root))
                .enter().append("path")
                .attr("d", arc)
                .attr("name", function (d) {
                    return d.name;
                })
                .style("fill", function (d) {
                    return color(d.data[airType]);
                })
                .on("click", function (d) {
                    svgSunBurst.transition()
                        .duration(750)
                        .tween("scale", function () {
                            var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
                                yd = d3.interpolate(y.domain(), [d.y, 1]),
                                yr = d3.interpolate(y.range(), [d.y ? 12 : 0, radius]);
                            return function (t) {
                                x.domain(xd(t));
                                y.domain(yd(t)).range(yr(t));
                            };
                        })
                        .selectAll("path")
                        .attrTween("d", function (d) {
                            return function () {
                                return arc(d);
                            };
                        });
                })
                .append("title")
                .text(function (d) {
                    return d.name + "\n" + airType + ": " + formatNumber(d.data[airType]);
                });
        });
    }

    function insertAllSunBurst(type, quarter, month) {
        graphLayer.innerHTML = "";
        for (key in cityCoordList) {
            insertSunBurstGraph(key, type, quarter, month);
        }
    }

    function insertLegend(airType) {
        $("#legend_g").html("");
        var startLocation = [100, 50];
        var size = 20;
        var maxValue = rangeList[airType][0], minValue = rangeList[airType][1];
        legendLayer.append('svg:text')
            .attr('x',startLocation[0]+0.5*size)
            .attr('y',startLocation[1]-0.5*size)
            .text(airType)
            .attr('fill','black')
            .attr('font-size',"10pt");
        for (var i = 0; i < colorList.length; i++) {
            var color = colorList[i];
            var value = (maxValue - minValue) * (colorList.length - i - 1) / colorList.length + minValue;
            legendLayer.append('rect')
                .attr('x', startLocation[0])
                .attr('y', startLocation[1] + i * size)
                .attr('width', size)
                .attr('height', size)
                .attr('fill', color);
            legendLayer.append('svg:text')
                .attr('x', startLocation[0] + 1.2 * size)
                .attr('y', startLocation[1] + (i + 0.8) * size)
                .text('≥' + d3.format('.2f')(value))
                .attr('fill',color)
                .attr("font-size", "10pt");
        }
    }

    function insertTitle() {
        svg.append('svg:text')
            .attr('x',320)
            .attr('y',50)
            .text('中国空气污染时空分布差异图')
            .attr('font-size','20pt')
            .attr('font-weight','bold');
    }
    insertAllSunBurst('AQI', -1, -1);
    insertLegend('AQI');
    insertTitle();

    $(document).ready(function () {
        $("#select_quarter").change(function () {
            var type = $("#select_index").val();
            var quarter = parseInt($("#select_quarter").val());
            insertAllSunBurst(type, quarter, -1);
        });
        $("#select_month").change(function () {
            var type = $("#select_index").val();
            var month = parseInt($("#select_month").val());
            if (month === -1)
                insertAllSunBurst(type, -1, -1);
            else {
                var quarter = Math.floor(month / 3);
                insertAllSunBurst(type, quarter, month - 3 * quarter);
            }


        });
        $("#select_index").change(function () {
            var type = $("#select_index").val();
            insertAllSunBurst(type, -1, -1);
            insertLegend(type);
        });
    })
</script>
<!--<label>中国空气污染地图</label>-->
<label style="position: relative;top: 5%;">指标: </label>
<select id="select_index" title="空气污染指标" style="position: relative;top: 5%;">
    <option>AQI</option>
    <option>PM25</option>
    <option>PM10</option>
    <option>CO</option>
    <option>O3</option>
    <option>SO2</option>
    <option>NO2</option>
</select>
<br>
<label style="position: relative;top: 5%;">季度: </label>
<select id="select_quarter" title="只显示该季度" style="position: relative;top: 5%;">
    <option value="-1">All</option>
    <option value="0">Q1</option>
    <option value="1">Q2</option>
    <option value="2">Q3</option>
    <option value="3">Q4</option>
</select>
<br>
<label style="position: relative;top: 5%;">月份: </label>
<select id="select_month" title="只显示该月份" style="position: relative;top: 5%;">
    <option value="-1">All</option>
    <option value="0">1月</option>
    <option value="1">2月</option>
    <option value="2">3月</option>
    <option value="3">4月</option>
    <option value="4">5月</option>
    <option value="5">6月</option>
    <option value="6">7月</option>
    <option value="7">8月</option>
    <option value="8">9月</option>
    <option value="9">10月</option>
    <option value="10">11月</option>
    <option value="11">12月</option>
</select>
</body>
</html>